#!/usr/bin/python
# -*- coding: UTF-8 -*-

"""this script intent to convert one tex file into a single html file with image support"""

import sys,os,re

if len(sys.argv)<2:
    print "usage",sys.argv[0],"[your tex file]"
    sys.exit()

class Convertor:
    def __init__(self,texpath):
        self.imgseed=0
        self.afterText=False
        self.src=os.path.abspath(texpath)
        if not os.path.exists(self.src):
            self.err("path %s not exists!" % (self.src))

    def err(self,info):
        print info
        sys.exit()

    def makeDestDir(self):
        self.targetName=os.path.basename(self.src).split(".")[0]
        self.basedir=os.path.abspath("./%s" % (self.targetName))
        if not os.path.exists(self.basedir):
            os.makedirs(self.basedir)
        self.outputpath="%s/%s.html" % (self.basedir,self.targetName)
        self.outfile=open(self.outputpath,"w")

    def seprateParagraphs(self):
        """we need seprate source file into head and several paragraphs"""
        self.paragraphs=[]
        self.headfile=open("%s/head.tex" % (self.basedir),"w")
        self.inHead=True
        self.processTexFile(self.src)

    def processTexFile(self,path):
        srcfile=open(path)
        while True:
            line=srcfile.readline()
            line=line.replace("\r","")
            if line=="\n":
                self.processDoubleLine()
                line=self.skipEmptyLine(srcfile)
            if line.strip().startswith("%"):continue
            if len(line)<=0:break
            if len(line.strip())<=0: continue
            if self.inHead:
                line=line.strip()
                if line=="\\begin{document}":
                    self.inHead=False
                    self.headfile.close()
                elif line.startswith("\\input{"):
                    path_=line.split("{")[1].split("}")[0]
                    self.processInclude(path_)
                else:
                    self.headfile.write(line+"\n")
            else:
                cmd=line
                if cmd.startswith("\\"):
                    if cmd.startswith("\\title"):self.title=cmd.split("{")[1].split("}")[0]
                    elif cmd.startswith("\\author"):self.author=cmd.split("{")[1].split("}")[0]
                    elif cmd.startswith("\\include{"):self.processInclude(cmd.split("{")[1].split("}")[0])
                    elif cmd.startswith("\\input{"):self.processInclude(cmd.split("{")[1].split("}")[0])
                    elif cmd.startswith("\\section{"):self.processSection(cmd.split("{")[1].split("}")[0])
                    elif cmd.startswith("\\subsection{"):self.outfile.write("<h2>%s</h2>\n" % (cmd.split("{")[1].split("}")[0]))
                    elif cmd.startswith("\\subsubsection{"):self.outfile.write("<h3>%s</h3>\n" % (cmd.split("{")[1].split("}")[0]))
                    elif cmd.startswith("\\begin{figure}"):self.processFigure(cmd,srcfile)
                    elif cmd.startswith("\\begin{table}"):self.processTable(cmd,srcfile)
                    elif cmd.startswith("\\begin{enumerate}"):self.processEnumerate(cmd,srcfile)
                    else:print "skip cmd:",cmd
                elif cmd.startswith("$"):self.processMath(cmd,srcfile)
                else:
                    self.processNormalText(cmd) 

    def processMath(self,cmd,srcfile):
        if cmd[1:].find("$")>0:
            cmd=cmd[:(cmd[1:].find("$")+2)]
        imgtexfile=open("%s/math.tex" % (self.basedir),"w")
        imgtexfile.write(cmd+"\n")
        imgtexfile.close()
        imgname=self.convertMath()
        self.outfile.write("<img src=\"%s\"/>" % (imgname))
        self.afterText=True
 

    def processEnumerate(self,cmd,srcfile):
        self.outfile.write("<ol>")
        while True:
            line=srcfile.readline()
            if len(line)<=0:break
            if line.strip().startswith("\end{enumerate}"):break
            if line.startswith("\item "):
                self.outfile.write("<li>%s</li>" % (self.removeTags(line[5:])))
        self.outfile.write("</ol>")

    def processTable(self,cmd,srcfile):
        self.outfile.write("<table border=\"1\">")
        while True:
            line=srcfile.readline()
            if len(line)<=0:break
            if line.strip().startswith("\end{table}"):break
            if line.find("&")>0:
                cells=line.split("&")
                self.outfile.write("<tr>")
                for cell in cells:
                    self.outfile.write("<td>%s</td>" % (self.removeTags(cell)))
                self.outfile.write("</tr>")
        self.outfile.write("</table>")

    def removeTags(self,txt):
        cnts=re.split("\\\\[a-z0-9\\*\\{\\}_\\:\\\\]*",txt)
        return "".join(cnts)

    def processFigure(self,cmd,srcfile):
        imgtexfile=open("%s/img.tex" % (self.basedir),"w")
        imgtexfile.write(cmd+"\n")
        while True:
            line=srcfile.readline()
            if len(line)==0: return
            if line.strip().startswith("\end{figure}"):
                imgtexfile.write(line)
                imgtexfile.close()
                break
            else:imgtexfile.write(line)
        imgname=self.convertImg()
        self.outfile.write("<img src=\"%s\"/>" % (imgname))
        self.afterText=True
    
    def system(self,dir,cmd):
        curdir=os.path.abspath(os.curdir)
        os.chdir(dir)
        os.system(cmd)
        os.chdir(curdir)

    def convertMath(self):
        self.imgseed+=1
        imgfile="img%d.png" % (self.imgseed)
        imgname="img%d" % (self.imgseed)
        tmpfile=open("%s/%s.tex" % (self.basedir,imgname),"w")
        tmpfile.write("\\include{head}\n")
        tmpfile.write("""
\usepackage{color}
\definecolor{bg}{rgb}{1,1,1}  % 背景颜色
\definecolor{fg}{rgb}{0,0,0}  % 前景颜色
\pagestyle{empty}
\pagecolor{bg}
""")
        tmpfile.write("\\begin{document}\n")
        tmpfile.write("\\include{math}\n")
        tmpfile.write("\\end{document}\n")
        tmpfile.close()
        self.system(self.basedir,"xelatex %s.tex" % (imgname))
        self.system(self.basedir,"pdftops -eps %s.pdf" % (imgname))
        self.system(self.basedir,"convert -density 72 -trim  -border 4x4 -bordercolor \\#FFFFFF -matte -transparent \\#EF0000 -type PaletteMatte %s.eps %s" % (imgname,imgfile))
        return imgfile

    def convertImg(self):
        self.imgseed+=1
        imgfile="img%d.png" % (self.imgseed)
        tmpfile=open("%s/tmp.tex" % (self.basedir),"w")
        tmpfile.write("\\include{head}\n")
        tmpfile.write("""
\usepackage[graphics,tightpage,active]{preview}
\PreviewEnvironment{tikzpicture}
\PreviewEnvironment{equation}
\PreviewEnvironment{equation*}
\\newlength{\imagewidth}
\\newlength{\imagescale}
\pagestyle{empty}
\\thispagestyle{empty}
""")
        tmpfile.write("\\begin{document}\n")
        tmpfile.write("\\include{img}\n")
        tmpfile.write("\\end{document}\n")
        tmpfile.close()
        self.system(self.basedir,"xelatex tmp.tex")
        self.system(self.basedir,"pdftops -eps tmp.pdf")
        self.system(self.basedir,"convert -density 72 tmp.eps %s" % (imgfile))
        return imgfile

    def skipEmptyLine(self,srcfile):
        while True:
            line=srcfile.readline()
            line=line.replace("\r","")
            if line!="\n":return line
        return ""

    def processDoubleLine(self):
        if self.afterText:
            self.outfile.write("<p/>\n\n")
            self.afterText=False

    def processSection(self,title):
        self.outfile.write("<h1>%s</h1>\n" % (title))

    def processNormalText(self,txt):
        pieces=re.split("(\\{\\\\bf[^\\}]*\\})",txt)
        txt=""
        for piece in pieces:
            if piece.startswith("{\\bf"):
                txt+="<b>%s</b>" % (piece.split("bf",1)[1].split("}")[0])
            else:
                txt+=piece
        self.outfile.write(self.removeTags(txt))
        self.afterText=True

    def processInclude(self,path):
        print "process include file",path
        if not path.endswith(".tex"):path+=".tex"
        if not os.path.exists(path):
            self.err("include path %s not exists!" % (path))
        self.processTexFile(path) 

    def outputHead(self):
        self.outfile.write("""
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
""")

    def outputBottom(self):
        self.outfile.write("""
</body>
</html>
""")

    def doConvert(self):
        self.makeDestDir()
        self.outputHead()
        self.seprateParagraphs()
        self.outputBottom()

if __name__=="__main__":
    c=Convertor(sys.argv[1])
    c.doConvert()
